package com.assistant.codegen.modules.model.domain;

import com.assistant.codegen.modules.model.domain.column.ColumnFactory;
import com.assistant.codegen.modules.model.domain.column.ModelColumn;
import com.assistant.codegen.modules.template.domain.Plan;
import com.assistant.framework.BaseDomain;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.beans.BeanUtils;

import javax.persistence.*;
import javax.persistence.Table;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 模型
 */
@EqualsAndHashCode(callSuper = true)
@ToString(exclude = "columns")
@Data
@Entity
@Table(name = "codegen_project_model")
public class Model extends BaseDomain<Model> {

    /**
     * 模型名称
     */
    private String name;
    /**
     * 注意需要首字母小写的驼峰格式
     */
    private String domainName;
    /**
     * 表名
     */
    private String tableName;
    /**
     * 所属的项目
     */
    @ManyToOne
    @JoinColumn(name = "project_id", foreignKey = @ForeignKey(name = "none"))
    private Project project;

    /**
     * 拥有的字段
     */
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "model_id", foreignKey = @ForeignKey(name = "none"))
    private List<ModelColumn> columns;

    /**
     * 所属模块
     */
    private String moduleName;

    /**
     * 所属子模块
     */
    private String subModuleName;

    /**
     * 备注信息
     */
    private String remarks;

    /**
     * 采用的方案
     */
    @ManyToOne
    @JoinColumn(name = "plan_id", foreignKey = @ForeignKey(name = "none"))
    private Plan plan;

    /**
     * 同步数据源中的内容
     */
    public void syncFromDataSource(String... ignoreColumn) throws SQLException {
        syncFromDataSource(true, ignoreColumn);
    }

    public void syncFromDataSource(boolean override, String... ignoreColumn) throws SQLException {
        final Project project = this.project;
        final DataSource dataSource = this.project.getDataSource();
        final List<ModelColumn> modelColumnList = ColumnFactory.create(dataSource, project.getDatabaseName(), tableName);
        final List<String> ignoreColumnList = Arrays.asList(ignoreColumn);
        final Map<String, ModelColumn> newColumnMap = modelColumnList.stream().filter(column -> {
            return !ignoreColumnList.contains(column.getColumnName());
        }).collect(Collectors.toMap(ModelColumn::getColumnName, Function.identity()));

        for (ModelColumn modelColumn : this.columns) {
            if (newColumnMap.containsKey(modelColumn.getColumnName())) {
                final ModelColumn newColumn = newColumnMap.remove(modelColumn.getColumnName());
                if (override) {
                    BeanUtils.copyProperties(newColumn, modelColumn, "id", "model", "sort");
                }
            }
        }
        if (!newColumnMap.isEmpty()) {
            this.columns.addAll(newColumnMap.values());
        }
    }
}
